﻿using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace GBAExtentionLib
{

    public class GameButton : Button
    {
        public GameButton()
        {
            DefaultStyleKey = typeof (Button);
        }

        protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
        {
            base.OnMouseEnter(e);
            GameButtonKeyService.GetInstance().PressKey(GameButtonKey);
        }

        protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e)
        {
            base.OnMouseLeave(e);
            GameButtonKeyService.GetInstance().ReleaseKey(GameButtonKey);
        }

        public static readonly DependencyProperty GameButtonKeyProperty =
            DependencyProperty.Register("GameButtonKey", typeof (GameButtonKey), typeof (GameButton),
                                        new PropertyMetadata(GameButtonKey.Null));

        public GameButtonKey GameButtonKey
        {
            get { return (GameButtonKey) GetValue(GameButtonKeyProperty); }
            set { SetValue(GameButtonKeyProperty, value); }
        }
    }

    /// <summary>
    /// 小于0不考虑，
    /// 2位表示单一按键值
    /// 4位表组合按键
    /// </summary>
    public enum GameButtonKey:short
    {
        Null=-1,
        A=0x00,
        B=0x01,
        L=0x09,
        R=0x08,
        Left=0x05,
        Up=0x06,
        Right=0x04,
        Down=0x07,
        Start=0x03,
        Select=0x02,
        LeftUp=0x0506,
        RightUp=0x0406,
        LeftDown=0x0507,
        RightDown=0x0407,
        AB=0x0001
    }

    public class GameButtonKeyService
    {
        /*
        private readonly List<GameButtonKey> _keyMap = new List<GameButtonKey>
            {
                GameButtonKey.A,
                GameButtonKey.B,
                GameButtonKey.Select,
                GameButtonKey.Start,
                GameButtonKey.Right,
                GameButtonKey.Left,
                GameButtonKey.Up,
                GameButtonKey.Down,
                GameButtonKey.R,
                GameButtonKey.L
            };*/

        private static GameButtonKeyService _instance;

        private readonly Dictionary<GameButtonKey, int> _keyState = new Dictionary<GameButtonKey, int>
            {
                {GameButtonKey.A, 0},
                {GameButtonKey.B, 0},
                {GameButtonKey.L, 0},
                {GameButtonKey.R, 0},
                {GameButtonKey.Left, 0},
                {GameButtonKey.Up, 0},
                {GameButtonKey.Right, 0},
                {GameButtonKey.Down, 0},
                {GameButtonKey.Start, 0},
                {GameButtonKey.Select, 0}
            };

        private GameButtonKeyService()
        {
        }

        public static GameButtonKeyService GetInstance()
        {
            return _instance ?? (_instance = new GameButtonKeyService());
        }

        public ushort GetKeyStates()
        {
            ushort keyreg = 0x3FF;

            foreach (var i in _keyState)
            {
                if (i.Value > 0)
                {
                    keyreg &= (ushort)(~(1U << (int)i.Key));
                }
                else
                {
                    keyreg |= (ushort)(1U << (int)i.Key);
                }
            }
            //for (int i = 0; i < _keyMap.Count; i++)
            //{
            //    if (_keyState[_keyMap[i]] > 0)
            //    {
            //        keyreg &= (ushort) (~(1U << i));
            //    }
            //    else
            //    {
            //        keyreg |= (ushort) (1U << i);
            //    }
            //}
            return keyreg;
        }

        public void PressKey(GameButtonKey button)
        {
            if (_keyState.ContainsKey(button))
            {
                _keyState[button]++;
            }
            else if ((short)button >= 100)//组合键处理
            {
                var b1 = ((short)button & 0xff00) >> 8;
                var b2 = (short) button & 0x00ff;
                if (_keyState.ContainsKey((GameButtonKey)b1))
                {
                    _keyState[(GameButtonKey)b1]++;
                }
                if (_keyState.ContainsKey((GameButtonKey)b2))
                {
                    _keyState[(GameButtonKey)b2]++;
                }
            }
        }

        public void ReleaseKey(GameButtonKey button)
        {
            if (_keyState.ContainsKey(button))
            {
                _keyState[button]--;
            }
            else if ((short)button >= 100)//组合键处理
            {
                var b1 = ((short)button & 0xff00) >> 8;
                var b2 = (short)button & 0x00ff;
                if (_keyState.ContainsKey((GameButtonKey)b1))
                {
                    _keyState[(GameButtonKey)b1]--;
                }
                if (_keyState.ContainsKey((GameButtonKey)b2))
                {
                    _keyState[(GameButtonKey)b2]--;
                }
            }
        }
    }

}
